package com.kehutong.charge.service.impl;

import com.kehutong.charge.dao.PayManagesDao;
import com.kehutong.charge.vo.PayBillRecordsExcelVO;
import com.kehutong.charge.entity.PayBillManages;
import com.kehutong.charge.entity.PayBillRecords;
import com.kehutong.charge.entity.ReceiptsStatistics;
import com.kehutong.charge.service.PayManagesService;
import com.kehutong.charge.util.PdfUtil;
import com.kehutong.common.DeptService;
import com.kehutong.common.dto.DeptDTO;
import com.kehutong.common.errcode.Assert;
import com.kehutong.common.excel.tool.ExcelTool;
import com.kehutong.common.urlconfig.FileUrlConfig;
import com.kehutong.common.util.ListUtils;
import com.kehutong.common.util.Token;
import org.coraframework.converter.util.StringUtil;
import org.coraframework.inject.Inject;
import org.coraframework.json.JSONArray;
import org.coraframework.json.JSONObject;
import org.coraframework.logger.Logger;
import org.coraframework.logger.LoggerFactory;
import org.coraframework.mvc.http.result.Result;
import org.coraframework.orm.Pool;
import org.coraframework.orm.jdbc.JdbcSession;
import org.coraframework.orm.jdbc.Page;
import org.coraframework.orm.jdbc.execute.Condition;
import org.coraframework.orm.jdbc.execute.QueryCondition;
import org.coraframework.orm.jdbc.execute.entity.FindPage;
import org.coraframework.util.Objects;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @program: kht
 * @description: PayManagesServiceImpl
 * @author: jian Ye
 * @create: 2021/8/3
 **/
public class PayManagesServiceImpl implements PayManagesService {

    private static final Logger logger = LoggerFactory.getLogger(PayManagesServiceImpl.class);

    @Inject
    private JdbcSession jdbcSession;
    @Inject
    FileUrlConfig fileUrlConfig;
    @Inject
    DeptService deptService;
    @Inject
    PayManagesDao payManagesDao;
    @Inject
    ExcelTool excelTool;



    @Override
    public Page<PayBillManages> findPage(JSONObject jsonObject) {
        FindPage<PayBillManages> find = jdbcSession.findPage(PayBillManages.class)
                .eq("deleted", false)
                .eq(jsonObject,"status")
                .like(jsonObject,"payBillName")
                .like(jsonObject,"communityList")
                .order("createTime", "desc")
                .page(jsonObject);
        return find.exe();
    }





    @Override
    public List<PayBillManages> findList(JSONObject jsonObject) {
        List<PayBillManages> receiptList = jdbcSession.findArray(PayBillManages.class)
                .eq("deleted", false)
                .eq("status",true)
                .like(jsonObject,"communityList")
                .exe();

        return receiptList;
    }


    @Override
    public Object save(PayBillManages payBillManages) throws Exception {
        return null;
    }


    @Override
    public Object save(PayBillManages entity, Token token) {
        JSONObject jsonO = new JSONObject();
        List<String> communityList = entity.getCommunityList();
        if(Objects.isEmpty(communityList) || StringUtil.isEmpty(entity.getSealImgId()) || StringUtil.isEmpty(entity.getRemark())){
            return Result.error(0, "有必填项目没有填，请先检查！");
        }
        //查询小区是否已存在模板
        for (int i = 0; i < communityList.size() ; i++) {
            jsonO.put("communityList",entity.getCommunityList().get(i));
            List<PayBillManages> listObj = findList(jsonO);
            if(null != listObj && listObj.size() > 0){
                return Result.error(0, "该小区模板已经存在，请先检查！");
            }
        }
        FileOutputStream outputFileStream = null;
        try {
            //获取上传的签章图片
            String fileImg = fileUrlConfig.getFile(entity.getSealImgId());
            PdfUtil pdfUtil = new PdfUtil();
            //保持时生成PDF文件保存到文件服务器
            byte[] pdf = pdfUtil.execute(pdfUtil.dataGenera(fileImg,entity.getPayBillName(),"payBill",entity.getRemark()));
            String pdfName = System.currentTimeMillis()+".pdf";
            File file = new File(pdfName);
            outputFileStream = new FileOutputStream(file);
            outputFileStream.write(pdf);
            JSONObject jsonObject =  fileUrlConfig.sendFile(file, http->{ });
            entity.setFileId(jsonObject.getJSONObject("data").getString("id"));

            List<String> departList = token.getDepartments();
            if(Objects.isEmpty(departList)){
                logger.error("用户{}数据异常，部门为空！",token.getUsername());
                return Result.error(0, "用户数据异常，生成收据失败！");
            }
            DeptDTO deptDTO = deptService.getDept(departList.get(0));
            entity.setDepartmentNo(deptDTO.getDepartmentNo());
            entity.setDepartmentNos(deptDTO.getDepartmentNos());
            entity.setDepartmentName(deptDTO.getDepartmentName());
            entity.setCreateName(token.getUsername());

            //文件上传成功后自动删除
            if (file.exists() && file.isFile() && file.delete()) {
                logger.info("{}本地文件已经删除!",pdfName);
            }
            return jdbcSession.insert(entity);
        } catch (Exception e) {
            logger.error("用户{}生成PDF失败！",token.getUsername(),e);
            return Result.error(0, "生成收据失败！");
        } finally {
            if (outputFileStream != null){
                try {
                    outputFileStream.close();
                } catch (IOException e) {
                    logger.error("用户{}生成PDF ,IOException！",token.getUsername(),e);
                }
            }
        }
    }

    @Override
    public List<ReceiptsStatistics> groupData(JSONObject jsonObject) {
        //本月date1 ,上个月date2
        String date1;
        String date2;
        String strDate = jsonObject.getString("statistTime");
        if(!StringUtil.isEmpty(strDate)){
            date1 = strDate.substring(0,7);
            int num = Integer.parseInt(date1.substring(5,7))-1;
            date2 = date1.substring(0,5) + String.format("%02d", num);
        }else {
            //2.根据小区统计数据
            Calendar cal = Calendar.getInstance();
            int year = cal.get(Calendar.YEAR);
            int monthly = cal.get(Calendar.MONTH) + 1;
            int month = cal.get(Calendar.MONTH);
            //本月 (0 代表前面补充0,10代表长度为10,d 代表参数为正数型)
            date1 = year +"-"+ String.format("%02d", monthly);
            //上一个月 (0 代表前面补充0,10代表长度为10,d 代表参数为正数型)
            date2 = year +"-"+String.format("%02d", month);
        }
        JSONArray array = jsonObject.getJSONArray("communitys");
        QueryCondition query = Condition.createQuery(false);
        query.in("communityNo",array);
        query.groupBy("monthTime");
        query.groupBy("communityNo");
        List<ReceiptsStatistics> statistic = payManagesDao.statistic(query);

        ReceiptsStatistics receipt;
        List<ReceiptsStatistics> statList = new ArrayList<>();
        for (int i = 0; i < array.size(); i++) {
            String communityId = array.getString(i);
            receipt = new ReceiptsStatistics();
            //根据小区ID筛选结果集
            List<ReceiptsStatistics> listByCommunity = statistic.stream().filter(s -> communityId.equals(s.getCommunityName()))
                    .collect(Collectors.toList());
            //本月和上月数量
            int total = 0;
            int lastMonthNum = 0;
            int currentMonthlyNum = 0;
            if(!Objects.isEmpty(listByCommunity)){
                ReceiptsStatistics currentsStatistics = listByCommunity.stream().filter(c -> c.getMonthTime().equals(date1)).findFirst().orElse(null);
                if(null != currentsStatistics){
                    currentMonthlyNum = currentsStatistics.getMonthlyNum();
                }
                ReceiptsStatistics lastStatistics = listByCommunity.stream().filter(c -> c.getMonthTime().equals(date2)).findFirst().orElse(null);
                if(null != lastStatistics){
                    lastMonthNum = lastStatistics.getMonthlyNum();
                }
                total = listByCommunity.stream().mapToInt(c->c.getMonthlyNum()).sum();
            }
            receipt.setCommunityName(communityId);
            receipt.setLastMonthNum(lastMonthNum);
            receipt.setMonthlyNum(currentMonthlyNum);
            receipt.setTotalNum(total);
            statList.add(receipt);
        }
        return statList;
    }

    @Override
    public Page<PayBillRecords> findPayPage(JSONObject jsonObject) {
        String search = jsonObject.getString("search");
        FindPage<PayBillRecords> find = jdbcSession.findPage(PayBillRecords.class)
                .eq("deleted", false)
                .like(jsonObject,"payBillNo")
                .eq(jsonObject,"communityNo")
                .like(jsonObject,"createTime");
        if(!Objects.isEmpty(search)){
            find.markBegin();
            find.like("payBillNo", search).or();
            find.like("payOrderNo", search).or();
            find.like("chargeName", search).or();
            find.like("houseInfo", search).or();
            find.like("createTime", search).or();
            find.markEnd();
        }
        //添加选中导出条件
        JSONArray exportIdList = jsonObject.getJSONArray("exportIdList");
        if(!Objects.isEmpty(exportIdList)){
            find.in("payBillNo",exportIdList);
        }
        find.order("createTime", "desc");
        find.page(jsonObject);

        return find.exe();
    }

    @Override
    public void payPageExport(HttpServletRequest req, HttpServletResponse resp, JSONObject jsonObject) {
        jsonObject.put("pageNo", 1);
        jsonObject.put("pageSize", Short.MAX_VALUE);
        List<PayBillRecords> list = findPayPage(jsonObject).getList();
        Assert.notEmpty(list,"导出失败！没有找到相关的缴费列表数据.");
        List<PayBillRecordsExcelVO> dtoList = ListUtils.copyList(list, PayBillRecordsExcelVO::new);
        excelTool.excelDownload(req,resp,dtoList,"缴费列表导出");
    }

    @Override
    public List<PayBillRecords> findBIllRecordListByHouseNo(String houseNo) {
        List<PayBillRecords> list = jdbcSession.findArray(PayBillRecords.class)
                .eq("deleted", false)
                .eq("houseBillNo",houseNo)
                .order("createTime","desc")
                .exe();
        return list;
    }


    @Override
    public Object update(PayBillManages payBillManages) throws Exception {
        return jdbcSession.updateById(payBillManages);
    }


    @Override
    public Object deleteById(String id) {
        PayBillManages result = Pool.get(PayBillManages.class, id);
        if (result != null) {
            result.setDeleted(true);
            jdbcSession.updateById(result);
        }
        return 1;
    }

}
